package m.common.model.util;

import m.common.model.FieldMeta;
import m.common.model.LinkTableMeta;
import m.common.model.Model;
import m.common.model.TableMeta;
import m.common.model.config.ModelConfig;
import m.system.RuntimeData;
import m.system.db.DBManager;
import m.system.db.DataSet;
import m.system.exception.MException;
import m.system.util.ClassUtil;
import m.system.util.StringUtil;
import m.system.util.SystemUtil;

import java.util.Map;

public class ModelQueryUtil {
	/** 
	 * 查询实体类
	 *  <T>
	 *  obj 查询的对象, 主键oid不能为空
	 * 
	 *  Exception
	 */
	public static <T extends Model> T getModel(T obj) throws Exception{
		return getModel(obj,0);
	}
	/**
	 * 查询实体类
	 *  <T>
	 *  obj 查询的对象, 主键oid不能为空
	 *  level 查询@LinkTableMeta属性,小于0就不往下查询 
	 * 
	 *  Exception
	 */
	@SuppressWarnings("unchecked")
	public static <T extends Model> T getModel(T obj, int level) throws Exception{
		if(null==obj || StringUtil.isSpace(obj.getOid())){
			return null;
		}
		// 获得对象的类型
		Class<T> clazz=(Class<T>) obj.getClass();
		T returnObject=clazz.getConstructor(new Class[]{}).newInstance();
		TableMeta tableMeta=ModelConfig.getTableMeta(clazz);
		if(null==tableMeta) throw new MException(ModelQueryUtil.class,clazz.getName()+"没有对应的表!");
		Map<String,FieldMeta> fieldMap=ModelConfig.getFieldMetaMap(clazz);
		Map<String,LinkTableMeta> linkTableMap=ModelConfig.getLinkTableMetaMap(clazz);
		StringBuilder fieldString=new StringBuilder(tableMeta.oidField());
		for(String key : fieldMap.keySet()){
			FieldMeta field=fieldMap.get(key);
			fieldString.append(",").append(field.name());
		}
		for(String key : linkTableMap.keySet()){
			LinkTableMeta field=linkTableMap.get(key);
			fieldString.append(",").append(field.name());
		}

		DataSet ds=DBManager.executeQuery("SELECT " + fieldString + " FROM " + tableMeta.name() + " WHERE "+tableMeta.oidField()+"=?",new String[]{obj.getOid()});
		if(ds.size()>0){
			returnObject.setOid(ds.get(String.class, 0, tableMeta.oidField()));
			for(String key : fieldMap.keySet()){
				FieldMeta field=fieldMap.get(key);
				Class<?> type=ClassUtil.getDeclaredField(clazz,key).getType();
				Object v=ds.get(type,0,field.name());
				try {
					if(v instanceof String){
						StringBuffer buffer=RuntimeData.testStaticDomain(clazz.getSimpleName() + "." + key);
						try {//字符型
							ClassUtil.setFieldValue(returnObject, key, buffer.append(v));
						}catch (Exception e){//字符型无法填充，则填成字符数组
							if(!StringUtil.isSpace((String)v))
								ClassUtil.setFieldValue(returnObject, key, ((String) v).split(","));
							else
								ClassUtil.setFieldValue(returnObject, key, new String[]{});
						}
					}else{
						ClassUtil.setFieldValue(returnObject, key, v);
					}
				}catch(Exception e) {
					SystemUtil.println(e.getMessage());
				}
			}
			for(String key : linkTableMap.keySet()){
				LinkTableMeta field=linkTableMap.get(key);
				Object value=ds.get(0, field.name());
				if(null!=value){
					Model bean=ClassUtil.newInstance(field.table());
					ClassUtil.setFieldValue(bean, "oid", value);
					ClassUtil.setFieldValue(returnObject, key, level>0?getModel(bean,level-1):bean);
				}else {//没值就放空对象, 和ModelQueryList.getModel 保持一致
					ClassUtil.setFieldValue(returnObject, key, ClassUtil.newInstance(field.table()));
				}
			}
		}
		if(StringUtil.isSpace(returnObject.getOid())) return null;
		return returnObject;
	}
}
